﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Cn.Edwon.Web.Support;
using Cn.Cellula.Biz.Port;
using Cn.Edwon.Spring;
using Cn.Cellula.Model.Content;
using Cn.Cellula.Client;
using Cn.Edwon.Web.HtmlControl;
using Cn.Edwon.Web.Script;
using Cn.Cellula.Model.System;
using System.Reflection;
using Cn.Cellula.Biz;
using System.Text;
using Cn.Edwon.Web.Ac;
using Cn.Cellula.Model.Content.Item;

namespace Cn.Cellula.MiniTopSite.Ws {
    public partial class _Item : PageSupport {
        IItemBiz biz = BizFactory.Get<IItemBiz>();
        String categoryKey = "";
        String queryKey = "";
        String action = "";
        String itemKey = "";
        protected void Page_Load(object sender, EventArgs e) {
            itemKey = Request.QueryString["id"];
            queryKey = Request.QueryString["iqk"];
            categoryKey = Request.QueryString["ck"];
            action = Request.QueryString["act"];

            String content = "";
            log.Debug("action:" + action);
            if (action == "list") {
                content = LoadItemsByCategory();
            } else if (action == "q") {
                content = LoadItemByQuery();
            } else if (action == "qr") {
                content = Report();
            } else if (action == "exp") {
                content = Export();
                Response.Clear();
                Response.Buffer = true;
                Response.ContentEncoding = System.Text.Encoding.Default;
                Response.ContentType = "application/csv";
                Response.AppendHeader("content-disposition", "attachment;filename=ItemQueryExport.csv");
            } else if (action == "qad") {
                content = LoadItemAtlData();
            } else if(action == "todo"){
                String todoRef = SiteConfig.Calendar.TodoRef;
                if (!String.IsNullOrEmpty(todoRef)) {
                    categoryKey = todoRef;
                    content = LoadItemsByCategory();
                } else {
                    content = "[]/*ref not set*/";
                    log.Warn("todo ref item key not setting");
                }
            } else {
                content = "[]/*unknown action*/";
            }
            Response.Write(content);
            Response.End();
        }
        private String FilterQueryData(String rVal) {
            if (String.IsNullOrEmpty(rVal))
                return "";
            else
                return rVal.Replace(":", "").Replace(",", "");
        }

        private String ParseQueryResult2Json(IList<Object> rList) {
            StringBuilder sb = new StringBuilder();
            for (int i=0;i<rList.Count;i++){
                Object[] eo = (Object[])rList[i];
                if (i > 0) {
                    sb.Append(",");
                }
                sb.Append("[");
                sb.Append("\"" + eo[ItemQueryItemIDX.item_key] + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.item_name]) + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.item_no]) + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.category_key]) + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.category_name]) + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.item_tags]) + "\"");
                sb.Append(",\"" + JsUtil.JsonDataFilter(eo[ItemQueryItemIDX.file_count]) + "\"");
                sb.Append("]");
            }
            return sb.ToString();
        }

        private String BuildQuerySQL(String rCategory,String rItemQueryKey, IList<VSysAtlEO> rAtlList,UserPower power,Boolean rExport) {
            String sql = "select item_key";
            if (!rExport) {
                sql += ",eo.item_name";
                sql += ",eo.category_key,eo.item_no,eo.item_tags,eo.category_name,eo.file_count ";
            }
            sql += " from v_item_list eo ";
            sql += " where eo.owner_key='" + this.OwnerKey + "' ";
            sql += " and (eo.dept_level is null or eo.dept_key='" + power.DeptKey + "' or eo.dept_level<" + power.DeptLevel + ") ";
            sql += " and (eo.visiable_role_level is null or eo.visiable_role_key='" + power.RoleKey + "' or  eo.visiable_role_level<" + power.RoleLevel + ") ";
            if (!String.IsNullOrEmpty(rItemQueryKey)) {
                rItemQueryKey = FilterQueryData(rItemQueryKey);
                sql += " and (eo.item_name like '%" + rItemQueryKey + "%' ";
                sql += " or eo.item_tags like '%" + rItemQueryKey + "%' ";
                sql += " or eo.item_desc like '%" + rItemQueryKey + "%') ";
            }
            sql += " and eo.category_key='" + categoryKey + "' ";
            for (int i = 0; i < rAtlList.Count; i++) {
                VSysAtlEO eo = rAtlList[i];
                String val = Request.QueryString["a" + i];
                if (!String.IsNullOrEmpty(val)) {
                    val = FilterQueryData(val);
                    if (eo.FieldType == CodeTypeDef.FormField.User
                        || eo.FieldType == CodeTypeDef.FormField.Item
                        || eo.FieldType == CodeTypeDef.FormField.Dept) {
                        sql += "and eo.item_key in (select sad.item_key from v_item_atl_data sad where ";
                        sql += "sad.atl_key='" + eo.AtlKey + "' and sad.ref_item_key='" + val + "')";
                    } else if (eo.FieldType == CodeTypeDef.FormField.Boolean
                        || eo.FieldType == CodeTypeDef.FormField.CheckBox
                        || eo.FieldType == CodeTypeDef.FormField.Radio
                        || eo.FieldType == CodeTypeDef.FormField.DropDownList) {
                        sql += "and eo.item_key in (select sad.item_key from v_item_atl_data sad where ";
                        sql += "sad.atl_key='" + eo.AtlKey + "' and sad.data_value='" + val + "')";
                    } else if (eo.FieldType == CodeTypeDef.FormField.Date
                        || eo.FieldType == CodeTypeDef.FormField.DateTime
                        || eo.FieldType == CodeTypeDef.FormField.YearMonth) {
                        String val2 = Request.QueryString["a" + i + "_2"];
                        if (!String.IsNullOrEmpty(val) || !String.IsNullOrEmpty(val2)) {
                            DateTime dv = DateTime.Now;
                            sql += " and eo.item_key in (select sad.item_key from v_item_atl_data sad where ";
                            sql += " sad.atl_key='" + eo.AtlKey + "' ";
                            if (!String.IsNullOrEmpty(val)) {
                                try {
                                    dv = Convert.ToDateTime(val);
                                } catch {
                                    log.Error("Invalid Datetime parm");
                                    continue; }
                                sql += " and unix_timestamp(sad.data_value) >= unix_timestamp('" + dv.ToString("yyyy-MM-dd hh:mm:ss") + "')";
                            }
                            if (!String.IsNullOrEmpty(val2)) {
                                try {
                                    dv = Convert.ToDateTime(val2);
                                } catch {
                                    log.Error("Invalid Datetime parm");
                                    continue;
                                }
                                sql += " and unix_timestamp(sad.data_value) <=unix_timestamp('" + dv.ToString("yyyy-MM-dd hh:mm:ss") + "')";
                            }
                            sql += " )";
                        }
                    } else if (eo.FieldType == CodeTypeDef.FormField.Year
                        || eo.FieldType==CodeTypeDef.FormField.Month){
                        String val2 = Request.QueryString["a" + i + "_2"];
                        if (!String.IsNullOrEmpty(val) || !String.IsNullOrEmpty(val2)) {
                            Int32 iv = 0;
                            sql += " and eo.item_key in (select sad.item_key from v_item_atl_data sad where ";
                            sql += " sad.atl_key='" + eo.AtlKey + "' ";
                            if (!String.IsNullOrEmpty(val)) {
                                try {
                                    iv = Convert.ToInt32(val);
                                } catch {
                                    log.Error("Invalid Datetime parm");
                                    continue;
                                }
                                sql += " and sad.data_value>=" + iv + " ";
                            }
                            if (!String.IsNullOrEmpty(val2)) {
                                try {
                                    iv = Convert.ToInt32(val2);
                                } catch {
                                    log.Error("Invalid Datetime parm");
                                    continue;
                                }
                                sql += " and sad.data_value<=" + iv + " ";
                            }
                            sql += "  )";
                        }
                    } else {
                        sql += "and eo.item_key in (select sad.item_key from v_item_atl_data sad where ";
                        sql += "sad.atl_key='" + eo.AtlKey + "' and sad.data_value like '%" + val + "%')";
                    }
                }
            }
            sql += " order by eo.item_name ";
            return sql;
        }

        private String LoadItemByQuery() {
            if (this.Actor == null) {
                return "[]/*Logout*/";
            }
            if (String.IsNullOrEmpty(categoryKey)) {
                return "[]/*category key lost*/";
            }

            IList<VSysAtlEO> atlList = biz.LoadSysAtlByCategory(categoryKey, this.Power);
            String atlJson = "[[";
            for (int i=0;i<atlList.Count;i++){
                VSysAtlEO eo = atlList[i];
                String val = Request.QueryString["a"+i];
                if (i > 0)
                    atlJson += ",";
                atlJson += "[\""+eo.AtlKey+"\",\""+eo.AtlName+"\",";
                if (!String.IsNullOrEmpty(val)) {
                    val = FilterQueryData(val);
                    if (eo.FieldType == CodeTypeDef.FormField.User
                        || eo.FieldType == CodeTypeDef.FormField.Item
                        || eo.FieldType == CodeTypeDef.FormField.Dept) {
                        atlJson += "\"ref\"";
                    } else if (eo.FieldType == CodeTypeDef.FormField.Boolean
                        || eo.FieldType == CodeTypeDef.FormField.CheckBox
                        || eo.FieldType == CodeTypeDef.FormField.Radio
                        || eo.FieldType == CodeTypeDef.FormField.DropDownList) {
                        atlJson += "\"ddl\"";
                    } else if (eo.FieldType == CodeTypeDef.FormField.Date
                        || eo.FieldType == CodeTypeDef.FormField.DateTime) {
                            String val2 = Request.QueryString["a" + i+"_2"];
                        atlJson += "\"dt\"";
                    } else {
                        atlJson += "\"text\"";
                    }
                } else {
                    atlJson += "\"\"";
                }
                atlJson += "]";
            }

            atlJson += "]";
            String sql = BuildQuerySQL(categoryKey, queryKey, atlList, this.Power, false);
            IList<Object> list = biz.ExcuteSqlQuery(sql);
            if (list != null && list.Count > 0) {
                atlJson += ",[" + ParseQueryResult2Json(list) + "]";
            } else {
                //没有扩展的数据，直接查ITEM
                atlJson += ",[]";
            }
            atlJson += "]";
            return atlJson;
        }

        private String LoadItemAtlData() {
            StringBuilder sb = new StringBuilder();
            sb.Append("[");
            try {
                IList<VItemAtlDataEO> list = biz.LoadAtlDataByItem(itemKey, this.OwnerKey, this.Power);
                if (list != null && list.Count > 0) {
                    for (int i = 0; i < list.Count; i++) {
                        VItemAtlDataEO eo = list[i];
                        if (i > 0)
                            sb.Append(",");
                        sb.Append("[");
                        sb.Append("\"" + eo.AtlKey + "\"");
                        sb.Append(",\"" + JsUtil.JsonDataFilter(eo.AtlName) + "\"");
                        sb.Append(",\"" + JsUtil.JsonDataFilter(eo.DataValue) + "\"");
                        if (eo.FieldType == CodeTypeDef.FormField.Item) {
                            sb.Append(",\"" + eo.RefItemKey + "\"");
                        } else {
                            sb.Append(",\"\"");
                        }
                        sb.Append("]");
                    }
                } else {
                    sb.Append("[\"\",\"扩展信息\",\"无\",\"\"]");
                }
            } catch (Exception ex) {
                sb.Append("[\"\",\"扩展信息\",\"" + JsUtil.JsonDataFilter(ex.Message) + "\",\"\"]");
            }
            try {
                TItemEO item = biz.Load<TItemEO>(itemKey);
                sb.Append(",[\"\",\"备注\",\"" + JsUtil.JsonDataFilter(item.ItemDesc) + "\",\"\"]");
            } catch (Exception ex) {
                sb.Append(",[\"\",\"备注\",\"" + JsUtil.JsonDataFilter(ex.Message) + "\",\"\"]");
            }
            sb.Append("]");
            return sb.ToString();
        }

        private String LoadItemsByCategory() {
            try {
                IItemBiz biz = BizFactory.Get<IItemBiz>();
                IList<VItemListEO> list = biz.LoadItemByCategory(categoryKey, this.OwnerKey, this.Power);
                String json = JsUtil.ParseEOList2Array<VItemListEO>(list, "ItemKey,ItemName,CategoryName");
                return json;
            } catch {
            }
            return "[]";
        }
        public class ItemQueryAtlDataExportIDX {
            public const int ItemKey = 0;
            public const int ItemName = 1;
            public const int CategoryName = 2;
            public const int AtlKey = 3;
            public const int DataValue = 4;
        }
        public class ItemQueryItemIDX {
            public const int item_key = 0;
            public const int item_name = 1;
            public const int category_key=2;
            public const int item_no=3;
            public const int item_tags=4;
            public const int category_name=5;
            public const int file_count=6;
        }

        private void BuildReportData(ref IList<VSysAtlEO> atlList, ref IList<Object> itemlist, ref IList<Object> datalist) {
            atlList = biz.LoadSysAtlByCategory(categoryKey, this.Power);
            String sql = BuildQuerySQL(categoryKey, queryKey, atlList, this.Power, false);
            itemlist = biz.ExcuteSqlQuery(sql);

            sql = "select ";
            sql += " iad.item_key";
            sql += ",iad.item_name";
            sql += ",iad.category_name";
            sql += ",iad.atl_key";
            sql += ",iad.data_value ";
            sql += " from v_item_atl_data iad ";
            sql += " where iad.item_key in (";
            sql += BuildQuerySQL(categoryKey, queryKey, atlList, this.Power, true);
            sql += " ) ";
            sql += " order by iad.item_key ";
            datalist = biz.ExcuteSqlQuery(sql);
        }

        private String Report() {
            IList<VSysAtlEO> atlList = new List<VSysAtlEO>();
            IList<Object> itemlist = new List<Object>();
            IList<Object> datalist = new List<Object>();
            BuildReportData(ref atlList, ref itemlist, ref datalist);
            if (itemlist != null && itemlist.Count > 0) {
                StringBuilder sbCol = new StringBuilder("");
                StringBuilder sbRow = new StringBuilder("");
                sbCol.Append("[\"名称\",\"\"]");
                sbCol.Append(",[\"编号\",\"\"]");
                foreach (VSysAtlEO atl in atlList) {
                    if (atl.IsReport == null || atl.IsReport == 0) continue;
                    sbCol.Append(",[\"" + atl.AtlName + "\",\"" + atl.CountRule + "\"]");
                }
                Boolean find = false;
                for (int i = 0; i < itemlist.Count; i++) {
                    Object[] eo = (Object[])itemlist[i];
                    if (i > 0)
                        sbRow.Append(",");
                    sbRow.Append("[");
                    sbRow.Append("\"" + eo[ItemQueryItemIDX.item_key] + "\"");
                    sbRow.Append(",\"" + eo[ItemQueryItemIDX.item_name] + "\"");
                    sbRow.Append(",\"" + eo[ItemQueryItemIDX.item_no] + "\"");
                    foreach (VSysAtlEO atl in atlList) {
                        if (atl.IsReport == null || atl.IsReport == 0) continue;
                        find = false;
                        foreach (Object[] data in datalist) {
                            if (data[ItemQueryAtlDataExportIDX.ItemKey].ToString() == eo[VItemListIDX.item_key].ToString()
                                && data[ItemQueryAtlDataExportIDX.AtlKey].ToString() == atl.AtlKey) {
                                sbRow.Append(",\"" + data[ItemQueryAtlDataExportIDX.DataValue] + "\"");
                                find = true;
                                break;
                            }
                        }
                        if (!find) {
                            sbRow.Append(",");
                        }
                    }
                    sbRow.Append("]");
                }
                return "[[" + sbCol.ToString() + "],[" + sbRow.ToString() + "]]";
            } else {
                return "[]";
            }
        }
        private String Export() {
            IList<VSysAtlEO> atlList = new List<VSysAtlEO>();
            IList<Object> itemlist = new List<Object>();
            IList<Object> datalist = new List<Object>();
            BuildReportData(ref atlList, ref itemlist, ref datalist);

            StringBuilder sbCol = new StringBuilder("");
            StringBuilder sbRow = new StringBuilder("");
            if (itemlist != null && itemlist.Count > 0) {
                sbCol.Append("名称");
                sbCol.Append(",编号");
                foreach (VSysAtlEO atl in atlList) {
                    if (atl.IsReport == null || atl.IsReport == 0) continue;
                    sbCol.Append("," + atl.AtlName);
                }
                Boolean find = false;
                for (int i = 0; i < itemlist.Count; i++) {
                    Object[] eo = (Object[])itemlist[i];
                    sbRow.Append("\r\n");
                    sbRow.Append(eo[VItemListIDX.item_name]);
                    sbRow.Append("," + eo[VItemListIDX.item_no]);
                    foreach (VSysAtlEO atl in atlList) {
                        if (atl.IsReport == null || atl.IsReport == 0) continue;
                        find = false;
                        foreach (Object[] data in datalist) {
                            if (data[ItemQueryAtlDataExportIDX.ItemKey].ToString() == eo[VItemListIDX.item_key].ToString()
                                && data[ItemQueryAtlDataExportIDX.AtlKey].ToString() == atl.AtlKey) {
                                    sbRow.Append("," + data[ItemQueryAtlDataExportIDX.DataValue]);
                                find = true;
                                break;
                            }
                        }
                        if (!find) {
                            sbRow.Append(",");
                        }
                    }
                }
            }
            return sbCol.ToString() + sbRow.ToString();
        }
    }
}